/**
 * JAVACC DEMO 1.0
 */
package com.apache.passport.aop;

import com.apache.api.vo.ParamsVo;
import com.apache.cache.util.Validator;
import com.apache.client.LogClient;
import com.apache.database.constant.SpringContextLoader;
import com.apache.database.constant.SystemTools;
import com.apache.database.db.IDao;
import com.apache.method.SystemRunnable;
import com.apache.passport.common.FileUtils;
import com.apache.passport.entity.LoginInfo;
import com.apache.passport.manager.LoginInfoManager;
import com.apache.passport.service.CacheHelper;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description:  拦截header,存储用户登录信息
 *
 * @author Hou Dayu 创建时间：2016-12-19
 */
public class LoginAopRunable extends SystemRunnable {

    private Logger log = Logger.getLogger(LoginAopRunable.class);

    IDao loginInfoDao;

    public void setLoginInfoDao(IDao loginInfoDao) {
        this.loginInfoDao = loginInfoDao;
    }

    /**
     * 创建文件标示 T/F
     */
    private String CRLGINFILEFLAG = SystemTools.getInstance().getValue("crLginFileFlag");

    private LoginInfoManager loginInfoManager;

    private LoginInfo loginInfo;

    private String operaType;

    public LoginAopRunable(LoginInfo loginInfo) {
        this.loginInfo = loginInfo;
    }

    public LoginAopRunable(LoginInfo loginInfo, String operaType) {
        this.loginInfo = loginInfo;
        this.operaType = operaType;
    }

    /**
     * TODO 多线程运行,防止堵塞
     *
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            ParamsVo<LoginInfo> param = new ParamsVo<LoginInfo>();
            param.setInfoId(loginInfo.getUserEname());
            saveLogInfo();//添加登录退出的日志
            //数据库必须保存日志
            saveInfo(param);
            //T写入本地文件,O使用缓存写入本地文件(x>100),P,使用高速缓存服务器(需要部署缓存服务)
            if ("T".equals(CRLGINFILEFLAG)) {
                FileUtils.getInstance().createLoginFile(param);
            } else if ("O".equals(CRLGINFILEFLAG)) {//使用缓存方式写文件,缓存大于100条的时候进行写入
                //useCacheBackFile(param);
                CacheHelper.getInstance().getCache("loginLogCache")
                        .createCacheObject(loginInfo.getTokenId(), loginInfo);
            } else if ("P".equals(CRLGINFILEFLAG)) {//使用高速缓存服务器进行日志记录

            } else if ("M".equals(CRLGINFILEFLAG)) {//如果为M,则使用定时器进行写文件,只负责向缓存中写文件
                CacheHelper.getInstance().getCache("loginLogCache")
                        .createCacheObject(loginInfo.getTokenId(), loginInfo);
            }
        } catch (Throwable e) {
            log.error(e);
            e.printStackTrace();
        }
    }

    /**
     * description:  添加登录退出的日志
     */
    private void saveLogInfo() {
        if ("login".equals(operaType) || "logout".equals(operaType)) {
            Map<String, Object> logMap = new HashMap<String, Object>();
            logMap.put("logOperationType", operaType);
            logMap.put("logClassName", "com.apache.uct.common.entity.User");
            logMap.put("logIp", loginInfo.getLgnLastipaddress());
            logMap.put("log_userEname", loginInfo.getUserEname());
            log.info("用户["+operaType+"] logMap->"+logMap);
            LogClient.getInstance().execute(logMap);//添加日志
        }
    }

    /**
     * description:  从缓存中取出所有对象,且保存到文件中,此处有文件个数限制
     *
     * @param param
     */
    private void useCacheBackFile(ParamsVo<LoginInfo> param) {
        //去除当前缓存中所有的key
        List<String> lst = CacheHelper.getInstance().getCache("loginLogCache").getAllKeys();
        int mt = lst.size() % 100;//每增加100条写一次数据
        if (mt == 0 && lst.size() != 0) {
            List<Object> listObj = CacheHelper.getInstance().getCache("loginLogCache")
                    .getObjects(lst);
            for (int i = 0; i < listObj.size(); i++) {
                LoginInfo info = (LoginInfo) listObj.get(i);
                param.setObjs(info);
                FileUtils.getInstance().createLoginFile(param);
            }
        }
    }

    /**
     * description: 将用户登录文件写入到数据库中 (更新而不是添加)
     *
     * @param param
     * @return
     */
    private Object saveInfo(ParamsVo<LoginInfo> param) {
        Object msg = null;
        //判断是否有数据
        Object obj = getLoginInfoManager().getInfoById(param);
        param.setObj(loginInfo);
        if (!Validator.isEmpty(obj)) {
            //存在数据则更新
            msg = getLoginInfoManager().editInfo(param);
        } else {
            //不存在则添加
            msg = getLoginInfoManager().saveInfo(param);
        }
        return msg;
    }

    /**
     * description:  获取Spring LoginInfoManager
     *
     * @return
     */
    private LoginInfoManager getLoginInfoManager() {
        if (null == loginInfoManager) {
            loginInfoManager = (LoginInfoManager) SpringContextLoader.getBean("loginInfoManager");
        }
        return loginInfoManager;
    }

}
